/**
 * 
 */
package ph.edu.ics.sp.graphisched;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTabbedPane;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import ph.edu.ics.sp.graphisched.gui.TableMatrixPanel;

/**
 * @author Kathrynne Joy M. De Leon
 * 
 */
public class PrintToFile implements GraphiSchedConstants {
	private JFrame frame;
	private String college;
	private String department;
	private String semester;
	private String acadYear;
	private ArrayList<String> categories = new ArrayList<String>();
	private ArrayList<CourseSummary> coursesScheduled;
	private JTabbedPane classrooms;
	private File saveFilePath;

	/**
	 * Constructor
	 */
	public PrintToFile(JFrame frame) {
		super();
		this.frame = frame;
	}
	
	/**
	 * Default Constructor
	 */
	public PrintToFile() {
		super();
	}

	/**
	 * @return the college
	 */
	public String getCollege() {
		return college;
	}

	/**
	 * @param college
	 *            the college to set
	 */
	public void setCollege(String college) {
		this.college = college;
	}

	/**
	 * @return the department
	 */
	public String getDepartment() {
		return department;
	}

	/**
	 * @param department
	 *            the department to set
	 */
	public void setDepartment(String department) {
		this.department = department;
	}

	/**
	 * @return the semester
	 */
	public String getSemester() {
		return semester;
	}

	/**
	 * @param semester
	 *            the semester to set
	 */
	public void setSemester(String semester) {
		this.semester = semester;
	}

	/**
	 * @return the acadYear
	 */
	public String getAcadYear() {
		return acadYear;
	}

	/**
	 * @param acadYear
	 *            the acadYear to set
	 */
	public void setAcadYear(String acadYear) {
		this.acadYear = acadYear;
	}

	/**
	 * @return the classrooms
	 */
	public JTabbedPane getClassrooms() {
		return classrooms;
	}

	/**
	 * @param classrooms
	 *            the classrooms to set
	 */
	public void setClassrooms(JTabbedPane classrooms) {
		this.classrooms = classrooms;
		setCoursesScheduled(classrooms);
	}

	/**
	 * sort lecture classes of a certain subject by section
	 */
	public ArrayList<ClassBox> sortLectures(
			final ArrayList<ClassBox> lecSections) {
		Collections.sort(lecSections, new Comparator<ClassBox>() {
			public int compare(final ClassBox lec1, final ClassBox lec2) {

				return (lec1.getSection().compareTo(lec2.getSection()));
			}
		});

		return lecSections;
	}

	/**
	 * sort all classes by their course code
	 */
	public static ArrayList<CourseSummary> sortAllClasses(
			final ArrayList<CourseSummary> allClasses) {
		Collections.sort(allClasses, new Comparator<CourseSummary>() {
			public int compare(final CourseSummary class1,
					final CourseSummary class2) {

				return (class1.getCourseCode()
						.compareTo(class2.getCourseCode()));
			}
		});

		return allClasses;
	}

	/**
	 * gets all lecture classes from the scheduled classes
	 */
	private void setCoursesScheduled(JTabbedPane classrooms) {
		coursesScheduled = new ArrayList<CourseSummary>();
		int numOfClassroomsWithSchedule = classrooms.getTabCount();
		for (int roomIndex = 0; roomIndex < numOfClassroomsWithSchedule; roomIndex++) {
			TableMatrixPanel tmp = ((TableMatrixPanel) classrooms
					.getComponentAt(roomIndex));
			ArrayList<ClassBox> coursesOnRoom = tmp.getClasses();
			int numOfCoursesOnRoom = coursesOnRoom.size();
			for (int courseIndex = 0; courseIndex < numOfCoursesOnRoom; courseIndex++) {
				ClassBox course = coursesOnRoom.get(courseIndex);
				if (course.getIsLecture()) {
					Course subj = course.getSubject();
					int i = checkIfCourseExists(subj.getCourseCode());
					if (i != -1) {
						((CourseSummary) coursesScheduled.get(i)).getLectures()
								.add(course);
					} else {
						if (!categories.contains(subj.getCategory())) {
							categories.add(subj.getCategory());
						}
						CourseSummary cs = new CourseSummary();
						cs.setCourseCode(subj.getCourseCode());
						cs.setCourseTitle(subj.getCourseTitle());
						cs.setPrerequisite(subj.getPrerequisite());
						cs.setSemOffered(subj.getSemesterOffered());
						cs.setUnits(subj.getUnits());
						cs.getLectures().add(course);
						cs.setCategory(subj.getCategory());
						coursesScheduled.add(cs);
					}
				}
			}
		}
		int numOfCourses = coursesScheduled.size();
		for (int i = 0; i < numOfCourses; i++) {
			coursesScheduled.get(i).setLectures(
					sortLectures(coursesScheduled.get(i).getLectures()));
		}
		coursesScheduled = sortAllClasses(coursesScheduled);
	}

	/**
	 * Categorize schduled courses
	 */
	private ArrayList<CourseSummary> categorize(String category) {
		ArrayList<CourseSummary> courses = new ArrayList<CourseSummary>();
		int size = coursesScheduled.size();
		for (int i = 0; i < size; i++) {
			CourseSummary cs = this.coursesScheduled.get(i);
			if (cs.getCategory().equals(category)) {
				courses.add(cs);
			}
		}
		return courses;
	}

	/**
	 * Checks if course has a data entry on courses scheduled
	 */
	private int checkIfCourseExists(String name) {
		int size = coursesScheduled.size();
		for (int i = 0; i < size; i++) {
			if (coursesScheduled.get(i).getCourseCode() == name) {
				return i;
			}
		}
		return -1;
	}

	@SuppressWarnings("deprecation")
	/**
	 * Converts or exports visual data to excel
	 */
	public void printToExcel() {
		JFileChooser saveFile = new JFileChooser();
		saveFile.setFileFilter(new ExcelFilter());
		saveFile.setAcceptAllFileFilterUsed(false);
		saveFile.setDialogTitle("Export To Excel");
		int returnVal = saveFile.showSaveDialog(frame);

		if (returnVal == JFileChooser.APPROVE_OPTION) {
			StringBuffer filename = new StringBuffer();
			filename.append(saveFile.getSelectedFile().getName());
			if (!filename.toString().endsWith(".xls")) {
				filename.append(".xls");
			}
			HSSFWorkbook wb = new HSSFWorkbook();
			// create a new file
			FileOutputStream out = null;
			try {
				out = new FileOutputStream(saveFile.getCurrentDirectory() + "/"
						+ filename);
				// create a new workbook
				wb = new HSSFWorkbook();
				// create a new sheet
				HSSFSheet s = wb.createSheet();
				// declare a row object reference
				HSSFRow r = null;
				// declare a cell object reference
				HSSFCell c = null;
				// declare cell styles
				HSSFCellStyle headingStyle = wb.createCellStyle();
				HSSFCellStyle subHeadingStyle = wb.createCellStyle();
				HSSFCellStyle bodyStyle = wb.createCellStyle();
				HSSFCellStyle bodyStyleCenter = wb.createCellStyle();
				HSSFCellStyle bodyStyleRight = wb.createCellStyle();
				// declare cell font
				HSSFFont HEADING_FONT = wb.createFont();
				HSSFFont SUB_HEADING_FONT = wb.createFont();
				HSSFFont BODY_FONT = wb.createFont();
				// cell style for body
				BODY_FONT.setFontHeightInPoints((short) 10);
				BODY_FONT.setFontName("Book Antiqua");
				BODY_FONT.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
				bodyStyle.setFont(BODY_FONT);
				bodyStyle
						.setDataFormat(HSSFDataFormat.getBuiltinFormat("text"));
				bodyStyleCenter.setFont(BODY_FONT);
				bodyStyleCenter.setDataFormat(HSSFDataFormat
						.getBuiltinFormat("text"));
				bodyStyleCenter.setAlignment(HSSFCellStyle.ALIGN_CENTER);
				bodyStyleRight.setFont(BODY_FONT);
				bodyStyleRight.setDataFormat(HSSFDataFormat
						.getBuiltinFormat("text"));
				bodyStyleRight.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
				// cell style for degree heading
				SUB_HEADING_FONT.setFontHeightInPoints((short) 10);
				SUB_HEADING_FONT.setFontName("Book Antiqua");
				SUB_HEADING_FONT.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
				subHeadingStyle.setFont(SUB_HEADING_FONT);
				// cell style for college and institute/department heading
				HEADING_FONT.setFontHeightInPoints((short) 12);
				HEADING_FONT.setFontName("Book Antiqua");
				HEADING_FONT.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
				headingStyle.setFont(HEADING_FONT);

				// edit sheet name
				wb.setSheetName(0, "Sched");
				// create heading
				// college
				r = s.createRow(ROW_TO_PRINT_COLLEGE);
				c = r.createCell((short) 0);
				c.setCellStyle(headingStyle);
				c.setCellValue(college);

				// department or institute
				r = s.createRow(ROW_TO_PRINT_DEPT);
				c = r.createCell((short) 0);
				c.setCellStyle(headingStyle);
				c.setCellValue(department);

				// course offering for semester and academic year
				r = s.createRow(ROW_TO_PRINT_COURSEOFFERING);
				c = r.createCell((short) 0);
				c.setCellStyle(headingStyle);
				StringBuffer courseOffering = new StringBuffer();
				courseOffering.append("Course Offering for ");
				courseOffering.append(semester);
				courseOffering.append(" Semester AY ");
				courseOffering.append(acadYear);
				c.setCellValue(courseOffering.toString());

				// print courses according to category
				int rownum = ROW_TO_PRINT_DEGREE;
				int numOfCategory = this.categories.size();
				for (int index = 0; index < numOfCategory; index++, rownum++) {
					String cat = this.categories.get(index);
					ArrayList<CourseSummary> coursesOnCategory = categorize(cat);
					// category
					r = s.createRow(rownum);
					c = r.createCell((short) 0);
					c.setCellStyle(subHeadingStyle);
					c.setCellValue(cat);
					rownum += 2;
					// body
					int size = coursesOnCategory.size();
					for (int i = 0; i < size; i++) {
						CourseSummary course = coursesOnCategory.get(i);
						// course name and title
						r = s.createRow(rownum);
						c = r.createCell((short) 0);
						c.setCellStyle(bodyStyle);
						c.setCellValue(course.getCourseCode());
						c = r.createCell((short) 1);
						c.setCellStyle(bodyStyle);
						c.setCellValue(course.getCourseTitle() + " ("
								+ course.getUnits() + ")");
						++rownum;

						// sem offered and prerequisite
						r = s.createRow(rownum);
						c = r.createCell((short) 0);
						c.setCellStyle(bodyStyle);
						c.setCellValue(course.getSemOffered());
						c = r.createCell((short) 1);
						c.setCellStyle(bodyStyle);
						c.setCellValue(course.getPrerequisite());
						++rownum;

						// list of lecture and lab schedules
						ArrayList<ClassBox> cbs = course.getLectures();
						int listOfLec = cbs.size();
						for (int j = 0; j < listOfLec; j++, rownum++) {
							ClassBox cb = cbs.get(j);
							r = s.createRow(rownum);
							if (cb.getSubject().getHasLaboratory() == 0) {
								// lecture label
								c = r.createCell((short) 1);
								c.setCellStyle(bodyStyle);
								c.setCellValue(SEC_LABEL);
							} else {
								// lecture label
								c = r.createCell((short) 1);
								c.setCellStyle(bodyStyle);
								c.setCellValue(LEC_LABEL);
							}
							// lecture section
							c = r.createCell((short) 2);
							c.setCellStyle(bodyStyle);
							c.setCellValue(cb.getSection());
							// time
							c = r.createCell((short) 3);
							c.setCellStyle(bodyStyleRight);
							c.setCellValue(cb.getTime());
							// day
							c = r.createCell((short) 4);
							c.setCellStyle(bodyStyleCenter);
							c.setCellValue(cb.getDay());
							// room
							c = r.createCell((short) 5);
							c.setCellStyle(bodyStyle);
							c.setCellValue(cb.getRoom());
							++rownum;
							// teacher
							c = r.createCell((short) 7);
							c.setCellStyle(bodyStyle);
							c.setCellValue(cb.getTeacher());

							// check if subject has laboratory
							if (cb.getSubject().getHasLaboratory() == 1
									&& !cb.getLaboratories().isEmpty()) {
								// laboratory(ies)
								r = s.createRow(rownum);
								// laboratory label
								c = r.createCell((short) 1);
								c.setCellStyle(bodyStyle);
								c.setCellValue(LAB_LABEL);

								ArrayList<ClassBox> labs = cb.getLaboratories();
								int numOfLab = cb.getLaboratories().size();
								for (int k = 0; k < numOfLab; k++, rownum++) {
									ClassBox lab = labs.get(k);
									r = s.createRow(rownum);
									// lab section
									c = r.createCell((short) 2);
									c.setCellStyle(bodyStyle);
									c.setCellValue(lab.getSection());
									// time
									c = r.createCell((short) 3);
									c.setCellStyle(bodyStyleRight);
									c.setCellValue(lab.getTime());
									// day
									c = r.createCell((short) 4);
									c.setCellStyle(bodyStyleCenter);
									c.setCellValue(lab.getDay());
									// room
									c = r.createCell((short) 5);
									c.setCellStyle(bodyStyle);
									c.setCellValue(lab.getRoom());
									// teacher
									c = r.createCell((short) 7);
									c.setCellStyle(bodyStyle);
									c.setCellValue(lab.getTeacher());
								}
							}
						}
					}
				}

				// set column widths
				short i = (short) (COL_1 * 256);
				s.setColumnWidth((short) 0, (short) i);
				i = (short) (COL_2 * 256);
				s.setColumnWidth((short) 1, (short) i);
				s.autoSizeColumn((short) 2);
				s.autoSizeColumn((short) 3);
				s.autoSizeColumn((short) 4);
				s.autoSizeColumn((short) 5);
				
				JOptionPane.showMessageDialog(null,
						"File exported to Excel successfully!", "Export File",
						JOptionPane.INFORMATION_MESSAGE);

			} catch (FileNotFoundException e) {
				JOptionPane
						.showMessageDialog(
								null,
								"Cannot write to file because it is being\nused by another process/program.\n You must close the file to proceed.",
								"Error", JOptionPane.ERROR_MESSAGE);
			}

			// write the workbook to the output stream
			// close our file (don't blow out our file handles
			try {
				wb.write(out);
			} catch (IOException e) {
				JOptionPane.showMessageDialog(null, "File not found!", "Error",
						JOptionPane.ERROR_MESSAGE);
			}
			try {
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
	}

	public int getIndexFromCourses(ArrayList<Course> courses, Course course) {
		int index = -1;
		index = courses.indexOf(course);
		return index;
	}

	/**
	 * Sets the file contents of the file to be written
	 */
	private String setFileContents(ArrayList<Course> courseList,
			ArrayList<String> roomsList) {
		StringBuffer fileContents = new StringBuffer();
		// <college value="college name">
		fileContents.append(COLLEGE_TAG);
		fileContents.append(this.college);
		fileContents.append(CLOSE_TAG);
		fileContents.append("\n");
		// <department value="department">
		fileContents.append(DEPT_TAG);
		fileContents.append(this.department);
		fileContents.append(CLOSE_TAG);
		fileContents.append("\n");
		// <semester value="sem">
		fileContents.append(SEM_TAG);
		fileContents.append(this.semester);
		fileContents.append(CLOSE_TAG);
		fileContents.append("\n");
		// <acadyear value="acadyear">
		fileContents.append(ACAD_YEAR_TAG);
		fileContents.append(this.acadYear);
		fileContents.append(CLOSE_TAG);
		fileContents.append("\n");
		// <courselist>
		fileContents.append(COURSE_LIST_TAG);
		// <course details="course","details">
		int size = courseList.size();
		for (int i = 0; i < size; i++) {
			Course c = courseList.get(i);
			fileContents.append("\n\t");
			fileContents.append(COURSE_TAG);
			fileContents.append("\"");
			fileContents.append(c.getCourseCode());
			fileContents.append("\",");
			fileContents.append("\"");
			fileContents.append(c.getCourseTitle());
			fileContents.append("\",");
			fileContents.append("\"");
			fileContents.append(c.getUnits());
			fileContents.append("\",");
			fileContents.append("\"");
			fileContents.append(c.getSemesterOffered());
			fileContents.append("\",");
			fileContents.append("\"");
			fileContents.append(c.getHasLaboratory());
			fileContents.append("\",");
			fileContents.append("\"");
			fileContents.append(c.getPrerequisite());
			fileContents.append("\",");
			fileContents.append("\"");
			fileContents.append(c.getLectureHoursPerWeek());
			fileContents.append("\",");
			fileContents.append("\"");
			fileContents.append(c.getLecSessionsPerWeek());
			fileContents.append("\",");
			fileContents.append("\"");
			fileContents.append(c.getLaboratoryHoursPerWeek());
			fileContents.append("\",");
			fileContents.append("\"");
			fileContents.append(c.getLaboratorySessionsPerWeek());
			fileContents.append("\",");
			fileContents.append("\"");
			fileContents.append(c.getCategory());
			fileContents.append("\"");
			fileContents.append(CLOSE_TAG);
		}
		fileContents.append("\n");
		fileContents.append(COURSE_LIST_END_TAG);
		fileContents.append("\n");
		// <rooms names="">
		fileContents.append(ROOMS_TAG);
		size = roomsList.size();
		for (int i = 0; i < size; i++) {
			if (i != size - 1) {
				fileContents.append(roomsList.get(i));
				fileContents.append(",");
			} else {
				fileContents.append(roomsList.get(i));
			}
		}
		fileContents.append(CLOSE_TAG);
		fileContents.append("\n");
		// <roomsscheduled names="">
		fileContents.append(ROOMSCHED_TAG);
		size = classrooms.getTabCount();
		for (int i = 0; i < size; i++) {
			if (i != size - 1) {
				fileContents.append(classrooms.getTitleAt(i));
				fileContents.append(",");
			} else {
				fileContents.append(classrooms.getTitleAt(i));
			}
		}
		fileContents.append(CLOSE_TAG);
		fileContents.append("\n");
		fileContents.append(COURSES_SCHED_TAG);
		size = coursesScheduled.size();
		for (int i = 0; i < size; i++) {
			ArrayList<ClassBox> lectures = coursesScheduled.get(i)
					.getLectures();
			int numOfLec = lectures.size();
			for (int j = 0; j < numOfLec; j++) {
				fileContents.append("\n\t");
				ClassBox cb = lectures.get(j);
				fileContents.append(SUBJECT_TAG);
				fileContents.append("\"");
				fileContents.append(getIndexFromCourses(courseList, cb
						.getSubject()));
				fileContents.append("\",");
				fileContents.append("\"");
				fileContents.append(cb.getColor());
				fileContents.append("\",");
				fileContents.append("\"");
				fileContents.append(cb.getWidth());
				fileContents.append("\",");
				fileContents.append("\"");
				fileContents.append(cb.getPoints().get(0));
				fileContents.append("\",");
				fileContents.append("\"");
				fileContents.append(cb.getIsLecture());
				fileContents.append("\",");
				fileContents.append("\"");
				fileContents.append(cb.getRoom());
				fileContents.append("\",");
				fileContents.append("\"");
				fileContents.append(cb.getTeacher());
				fileContents.append("\"");
				fileContents.append(CLOSE_TAG);
				if (cb.getSubject().getHasLaboratory() != 0
						&& cb.getLaboratories().size() != 0) {
					ArrayList<ClassBox> labs = cb.getLaboratories();
					int numOfLab = labs.size();
					for (int k = 0; k < numOfLab; k++) {
						fileContents.append("\n\t\t");
						ClassBox lab = labs.get(k);
						fileContents.append(LAB_TAG);
						fileContents.append("\"");
						fileContents.append(getIndexFromCourses(courseList, lab
								.getSubject()));
						fileContents.append("\",");
						fileContents.append("\"");
						fileContents.append(cb.getColor());
						fileContents.append("\",");
						fileContents.append("\"");
						fileContents.append(lab.getWidth());
						fileContents.append("\",");
						fileContents.append("\"");
						fileContents.append(lab.getPoints().get(0));
						fileContents.append("\",");
						fileContents.append("\"");
						fileContents.append(lab.getIsLecture());
						fileContents.append("\",");
						fileContents.append("\"");
						fileContents.append(lab.getRoom());
						fileContents.append("\",");
						fileContents.append("\"");
						fileContents.append(lab.getTeacher());
						fileContents.append("\"");
						fileContents.append(CLOSE_TAG);
					}
				}
			}
		}
		fileContents.append("\n");
		fileContents.append(COURSES_SCHED_END_TAG);
		return fileContents.toString();
	}
	
	/**
	 * Writes or outputs contents to file
	 */
	public void writeToFile(ArrayList<Course> courseList,
			ArrayList<String> roomsList) {
		Writer output = null;
		// collect file contents
		String fileContents = this.setFileContents(courseList, roomsList);

		try {
			output = new BufferedWriter(new FileWriter(saveFilePath));
			output.write(fileContents.toString());
			output.close();
			JOptionPane.showMessageDialog(null, "File saved successfully!",
					"Save File", JOptionPane.INFORMATION_MESSAGE);
		} catch (IOException e) {
			JOptionPane.showMessageDialog(null,
					"An error occured while writing to file!", "Error",
					JOptionPane.ERROR_MESSAGE);
		}
	}

	/**
	 * Saves the file
	 */
	public void saveToFile(ArrayList<Course> courseList,
			ArrayList<String> roomsList, boolean saveAsMode) {

		if (saveAsMode) {
			JFileChooser saveFile = new JFileChooser();
			saveFile.setFileFilter(new GSCFilter());
			saveFile.setDialogTitle("Save Graphi-Sched File");
			saveFile.setAcceptAllFileFilterUsed(false);
			int returnVal = saveFile.showSaveDialog(frame);

			if (returnVal == JFileChooser.APPROVE_OPTION) {
				StringBuffer filename = new StringBuffer();
				filename.append(saveFile.getSelectedFile().getName());
				if (!filename.toString().endsWith(".gsc")) {
					filename.append(".gsc");
				}

				this.saveFilePath = new File(saveFile.getCurrentDirectory()
						+ "/" + filename.toString());
				this.writeToFile(courseList, roomsList);
			}
		} else {
			this.writeToFile(courseList, roomsList);
		}
	}

	/**
	 * @return the saveFilePath
	 */
	public File getSaveFilePath() {
		return saveFilePath;
	}

	/**
	 * @param saveFilePath
	 *            the saveFilePath to set
	 */
	public void setSaveFilePath(File saveFilePath) {
		this.saveFilePath = saveFilePath;
	}

	/**
	 * Collects the details from a classbox as csv 
	 */
	private String appendDetails(ClassBox cb) {
		StringBuffer fileContents = new StringBuffer();
		String quote = "\"";
		fileContents.append(quote);
		fileContents.append(cb.getSection());
		fileContents.append(quote);
		fileContents.append(",");
		fileContents.append(quote);
		fileContents.append(cb.getTime());
		fileContents.append(quote);
		fileContents.append(",");
		fileContents.append(quote);
		fileContents.append(cb.getDay());
		fileContents.append(quote);
		fileContents.append(",");
		fileContents.append(quote);
		fileContents.append(cb.getRoom());
		fileContents.append(quote);
		fileContents.append(",");
		fileContents.append(quote);
		fileContents.append(quote);
		fileContents.append(",");
		if (cb.getTeacher() == null) {
			fileContents.append(quote);
			fileContents.append(quote);
		} else {
			fileContents.append(quote);
			fileContents.append(cb.getTeacher());
			fileContents.append(quote);
		}
		fileContents.append("\n");
		return fileContents.toString();
	}

	/**
	 * Sets the contents of the csv file to be written
	 */
	private String setFileContents() {
		StringBuffer fileContents = new StringBuffer();
		String quote = "\"";
		fileContents.append(quote);
		fileContents.append(this.getCollege());
		fileContents.append(quote);
		fileContents.append("\n");
		fileContents.append(quote);
		fileContents.append(this.getDepartment());
		fileContents.append(quote);
		fileContents.append("\n\n");
		fileContents.append(quote);
		fileContents.append("Course Offering for ");
		fileContents.append(this.getSemester());
		fileContents.append(" Semester AY ");
		fileContents.append(this.getAcadYear());
		fileContents.append(quote);
		fileContents.append("\n\n");

		int numOfCategories = this.categories.size();
		for (int i = 0; i < numOfCategories; i++) {
			String cat = this.categories.get(i);
			ArrayList<CourseSummary> coursesOnCategory = categorize(cat);
			fileContents.append(quote);
			fileContents.append(cat);
			fileContents.append(quote);
			fileContents.append("\n\n");

			int coursesSize = coursesOnCategory.size();
			for (int j = 0; j < coursesSize; j++) {
				CourseSummary course = coursesOnCategory.get(j);
				fileContents.append(quote);
				fileContents.append(course.getCourseCode());
				fileContents.append(quote);
				fileContents.append(",");
				fileContents.append(quote);
				fileContents.append(course.getCourseTitle());
				fileContents.append("(");
				fileContents.append(course.getUnits());
				fileContents.append(")");
				fileContents.append(quote);
				fileContents.append("\n");
				fileContents.append(quote);
				fileContents.append(course.getSemOffered());
				fileContents.append(quote);
				fileContents.append(",");
				fileContents.append(quote);
				fileContents.append(course.getPrerequisite());
				fileContents.append(quote);
				fileContents.append("\n");

				ArrayList<ClassBox> cbs = course.getLectures();
				int numOfLec = cbs.size();
				for (int k = 0; k < numOfLec; k++) {
					ClassBox cb = cbs.get(k);
					fileContents.append(quote);
					fileContents.append(quote);
					fileContents.append(",");
					if (cb.getSubject().getHasLaboratory() == 1) {
						fileContents.append(quote);
						fileContents.append(LEC_LABEL);
						fileContents.append(quote);
						fileContents.append(",");
					} else {
						fileContents.append(quote);
						fileContents.append(SEC_LABEL);
						fileContents.append(quote);
						fileContents.append(",");
					}
					fileContents.append(this.appendDetails(cb));
					int labSize = cb.getLaboratories().size();
					if (labSize != 0) {
						for (int l = 0; l < labSize; l++) {
							ClassBox lab = cb.getLaboratories().get(l);
							fileContents.append(quote);
							fileContents.append(quote);
							fileContents.append(",");
							fileContents.append(quote);
							fileContents.append(LAB_LABEL);
							fileContents.append(quote);
							fileContents.append(",");
							fileContents.append(this.appendDetails(lab));
						}
					}
					fileContents.append("\n");
				}
			}
			fileContents.append("\n");
		}
		return fileContents.toString();
	}

	/**
	 * Writes or outputs data to file
	 */
	public void writeToFile(File filePath) {
		Writer output = null;
		// collect file contents
		String fileContents = this.setFileContents();

		try {
			output = new BufferedWriter(new FileWriter(filePath));
			output.write(fileContents);
			output.close();
			JOptionPane.showMessageDialog(null, "File saved successfully!",
					"Save File", JOptionPane.INFORMATION_MESSAGE);
		} catch (IOException e) {
			JOptionPane.showMessageDialog(null,
					"An error occured while writing to file!", "Error",
					JOptionPane.ERROR_MESSAGE);
		}
	}

	/**
	 * Converts or exports visual data to csv
	 */
	public void printToCSV() {
		JFileChooser saveFile = new JFileChooser();
		saveFile.setFileFilter(new CSVFilter());
		saveFile.setDialogTitle("Export to CSV");
		saveFile.setAcceptAllFileFilterUsed(false);
		int returnVal = saveFile.showSaveDialog(frame);

		if (returnVal == JFileChooser.APPROVE_OPTION) {
			StringBuffer filename = new StringBuffer();
			filename.append(saveFile.getSelectedFile().getName());
			if (!filename.toString().endsWith(".csv")) {
				filename.append(".csv");
			}

			File filePath = new File(saveFile.getCurrentDirectory() + "/"
					+ filename.toString());
			this.writeToFile(filePath);
		}
	}

}
